package com.wanyu.video.netty.codec;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

import java.util.concurrent.TimeUnit;

/**
 * 自定义一个符合netty规则的Handler
 */
public class NettyServerSimpleHandler extends ChannelInboundHandlerAdapter {


    /**
     * 重写读取数据接口
     * @param ctx 上下文对象，含有管道（Pipeline）、通道（Channel）、地址
     * @param msg 客户端发送的数据
     * @throws
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println(" server ctx = " + ctx);
        ByteBuf byteBuf = (ByteBuf) msg;
        try {
            System.out.println("客户端发送的消息是： " + byteBuf.toString(CharsetUtil.UTF_8));
            System.out.println("客户端地址 ： " + ctx.channel().remoteAddress());

            // do something 如果这里执行比较耗时，就需要进行优化，使用一步执行，提交到该channel对应的NIOEventLoop的taskQueue中
            // 解决方案1 用户程序自定义的普通任务
            ctx.channel().eventLoop().execute(() -> {
                // 伪装成业务代码执行时间
                try {
                    Thread.sleep(10 * 1000);
                    // 将数据写入到缓冲区并刷新,目的是返回给client消息
                    ctx.writeAndFlush(Unpooled.copiedBuffer("hello, after ten seconds client business is done...", CharsetUtil.UTF_8));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });

            ctx.channel().eventLoop().execute(() -> {
                // 伪装成业务代码执行时间
                try {
                    Thread.sleep(20 * 1000);
                    // 将数据写入到缓冲区并刷新,目的是返回给client消息
                    ctx.writeAndFlush(Unpooled.copiedBuffer("hello, after twenty seconds client business is done...", CharsetUtil.UTF_8));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });

            // 用户自定义定时任务 -> 任务不会被提交taskQueue中，会提交到定时任务列表中
            ctx.channel().eventLoop().schedule(() -> ctx.writeAndFlush(Unpooled.copiedBuffer("hello, self definition schedule is done...", CharsetUtil.UTF_8)),
                    10, TimeUnit.SECONDS);
            ctx.writeAndFlush(Unpooled.copiedBuffer("hello client, 我收到你的消息了", CharsetUtil.UTF_8));
        } finally {
            byteBuf.release();
        }
    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}
